package com.ruihui.activity.controller;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ruihui.activity.exceprion.GetException;
import com.ruihui.activity.pojo.Acgoods;
import com.ruihui.activity.pojo.Acgroup;
import com.ruihui.activity.service.AcgoodsService;
import com.ruihui.activity.service.AcgroupService;
import com.ruihui.activity.util.AcgoodsType;
import com.ruihui.activity.util.ConstantHolder;
import com.ruihui.activity.util.DateUtil;
import com.ruihui.activity.util.Result;
import com.ruihui.activity.util.Validate;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * 活动优惠券
 * 
 * @author cf
 *
 */
@Api(tags = "活动团购前台")
@RestController
@RequestMapping("/webGroupActive")
public class WebActiveGroupController {
	private static final Logger log = LoggerFactory.getLogger(WebActivePonController.class);
	@Autowired
	private AcgoodsService acgoodsService;
	@Autowired
	private StringRedisTemplate redisTemplate;
	@Autowired
	private AcgroupService acgrouopService;
	@Autowired
	private Redisson redisson;

	/**
	 * 查询团购列表
	 * 
	 * @param goodsid
	 * @return
	 */
	@ApiOperation(value = "查询团购列表", response = Acgroup.class)
	@ApiImplicitParams({ @ApiImplicitParam(name = "goodsid", value = "goodsid", required = true, paramType = "query") })
	@PostMapping("/acgrouplist")
	public Object acgrouplist(@RequestParam Long goodsid) {
		List<List<Acgroup>> li = new ArrayList<>();
		long nowdate = DateUtil.getDateline();
		String types = AcgoodsType.NOTREPETITION;
		try {

			/*
			 * 验证是否是活动商品
			 */
			Acgoods acgoods = acgoodsService.iniacGoods(goodsid, nowdate, types);
			checkArgument(!StringUtils.isEmpty(acgoods), "活动已过期");
			/*
			 * 分组查询活动时间内未解散的团组
			 */
			List<Acgroup> acgroups = acgrouopService.selectList(new EntityWrapper<Acgroup>()
					.in("state", Acgroup.NOTDISMISS).between("starttime", acgoods.getStarttime(), acgoods.getEndtime())
					.eq("goodsid", goodsid).eq("paystatus", Acgroup.OP).groupBy("groupno")
					.where("{0} between starttime and endtime", nowdate));
			/*
			 * 团组以及团组成员集合
			 */
			li = acgroups.stream().map(ac -> {
				return acgrouopService
						.selectList(new EntityWrapper<Acgroup>().eq("groupno", ac.getGroupno()).orderBy("createtime"));
			}).collect(Collectors.toList());

			return li;
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

	/**
	 * 创建团购
	 * 
	 * @param sessionid
	 * @param goodsid
	 * @param username
	 * @param orderid
	 * @return
	 */
	@ApiOperation(value = "创建团购", response = Acgroup.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sessionid", value = "sessionid", required = true, paramType = "query"),
			@ApiImplicitParam(name = "goodsid", value = "商品id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "username", value = "用户名称", required = true, paramType = "query"),
			@ApiImplicitParam(name = "orderid", value = "订单id", required = true, paramType = "query") })
	@PostMapping("/createacgroup")
	public Object createacgroup(@RequestParam String sessionid, @RequestParam Long goodsid,
			@RequestParam String username, @RequestParam Long orderid) {

		try {
			int createcount = 0, createGroupCode = 0;
			// double hours=0.00;
			long nowdate = DateUtil.getDateline();
			String types = AcgoodsType.NOTREPETITION;
			Integer memberId = Validate.validateLogin(sessionid, redisTemplate);
			// 验证是否是活动商品
			Acgoods acgoods = acgoodsService.iniacGoods(goodsid, nowdate, types);
			checkArgument(!StringUtils.isEmpty(acgoods), "活动已过期");
			// hours=DateUtil.getBetweenHourTime(nowdate,
			// acgoods.getEndtime().longValue());
			// checkArgument(hours>24, "距离活动结束时间不足24小时");
			checkArgument(!StringUtils.isEmpty(acgoods.getGroupnum()), "活动不可创建");
			createcount = acgrouopService.getCreateCount(memberId, goodsid, acgoods);
			checkArgument(createcount == 0, "您已经创建过一次团购，此商品不能再加入了");
			createGroupCode = acgrouopService.createGroup(acgoods, memberId, goodsid, orderid, username);
			checkArgument(createGroupCode == 1, "创建失败");
			return Result.success();
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

	/**
	 * 加入团购
	 * 
	 * @param sessionid
	 * @param goodsid
	 * @param username
	 * @param orderid
	 * @param groupno
	 *            团号
	 * @return
	 */
	@ApiOperation(value = "加入团购", response = Acgroup.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sessionid", value = "sessionid", required = true, paramType = "query"),
			@ApiImplicitParam(name = "goodsid", value = "商品id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "username", value = "用户名称", required = true, paramType = "query"),
			@ApiImplicitParam(name = "orderid", value = "订单id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "groupno", value = "团号", required = true, paramType = "query") })
	@PostMapping("/addacgroup")
	public Object addacgroup(@RequestParam String sessionid, @RequestParam Long goodsid, @RequestParam String username,
			@RequestParam Long orderid, @RequestParam String groupno) {
		boolean flag = false;
		try {
			String lockKey = String.format(ConstantHolder.LOCK, groupno);
			int addcount = 0, addGroupCode = 0;
			boolean isHead = false;
			long nowdate = DateUtil.getDateline();
			String types = AcgoodsType.NOTREPETITION;
			Integer memberId = Validate.validateLogin(sessionid, redisTemplate);
			// 验证是否是活动商品
			Acgoods acgoods = acgoodsService.iniacGoods(goodsid, nowdate, types);
			checkArgument(!StringUtils.isEmpty(acgoods), "活动已过期");
			checkArgument(!StringUtils.isEmpty(acgoods.getGroupnum()), "团购人数未设置，不可加入");
			// 活动期间未加入任何一个团组并且非此团团长
			addcount = acgrouopService.getAddCount(memberId, goodsid, acgoods);
			isHead = acgrouopService.isHead(memberId, groupno);
			checkArgument(addcount == 0, "您已经加入过一次团购，此商品不能再加入了");
			checkArgument(!isHead, "团长不可加入自己创建的团组");
			RLock lock = redisson.getFairLock(lockKey);
			try {
				flag = lock.tryLock(5, 30, TimeUnit.SECONDS);
				if (flag) {
					addGroupCode = acgrouopService.addGroup(memberId, groupno, orderid, username);
				}
			} finally {
				lock.unlock();
			}

			checkArgument(addGroupCode == 1, "加入失败");
			return Result.success();
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

	/**
	 * 退出团购
	 * 
	 * @param sessionid
	 * @param goodsid
	 * @param username
	 * @param orderid
	 * @param groupno
	 *            团号
	 * @return
	 */
	@ApiOperation(value = "退出团购", response = Acgroup.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sessionid", value = "sessionid", required = true, paramType = "query"),
			@ApiImplicitParam(name = "goodsid", value = "商品id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "groupno", value = "团号", required = true, paramType = "query") })
	@PostMapping("/backacgroup")
	public Object backacgroup(@RequestParam String sessionid, @RequestParam Long goodsid,
			@RequestParam String groupno) {
		boolean flag = false;
		try {
			String lockKey = String.format(ConstantHolder.LOCK, groupno);
			int backGroupCode = 0;
			long nowdate = DateUtil.getDateline();
			String types = AcgoodsType.NOTREPETITION;
			Integer memberId = Validate.validateLogin(sessionid, redisTemplate);
			// 验证是否是活动商品
			Acgoods acgoods = acgoodsService.iniacGoods(goodsid, nowdate, types);
			checkArgument(!StringUtils.isEmpty(acgoods), "活动已过期");
			checkArgument(!StringUtils.isEmpty(acgoods.getGroupnum()), "团购人数未设置，系统错误");

			RLock lock = redisson.getFairLock(lockKey);
			try {
				flag = lock.tryLock(5, 30, TimeUnit.SECONDS);
				if (flag) {
					backGroupCode = acgrouopService.backGroup(memberId, groupno);
				}
			} finally {
				lock.unlock();
			}
			checkArgument(backGroupCode == 1, "退出失败");
			return Result.success();
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

	/**
	 * 团购订单申请退款，退款，发货，收货
	 * 
	 * @param sessionid
	 * @param goodsid
	 * @param username
	 * @param orderid
	 * @param groupno
	 *            团号
	 * @return
	 */
	@ApiOperation(value = "团购订单申请退款，退款，发货，收货", response = Acgroup.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sessionid", value = "sessionid", required = true, paramType = "query"),
			@ApiImplicitParam(name = "otype", value = "2申请退款3退款4发货5收货", required = true, paramType = "query"),
			@ApiImplicitParam(name = "orderid", value = "订单id", required = true, paramType = "query") })
	@PostMapping("/backpay")
	public Object backpay(@RequestParam String sessionid, @RequestParam Integer otype, @RequestParam Long orderid,
			@RequestParam Long goodsid) {

		boolean flag = false;
		try {
			String lockKey = String.format(ConstantHolder.LOCK, orderid);
			int backpayCode = 0;
			long nowdate = DateUtil.getDateline();
			String types = AcgoodsType.NOTREPETITION;
			// 验证是否是活动商品(此处验证预留，根据具体需求再做开发)
			Acgoods acgoods = acgoodsService.iniacGoods(goodsid, nowdate, types);
			checkArgument(otype == Acgroup.OEB || otype == Acgroup.OSB || otype == Acgroup.OPG || otype == Acgroup.OPP,
					"参数类型输入错误");
			Integer memberId = Validate.validateLogin(sessionid, redisTemplate);
			RLock lock = redisson.getFairLock(lockKey);
			try {
				flag = lock.tryLock(5, 30, TimeUnit.SECONDS);
				if (flag) {
					backpayCode = acgrouopService.backpay(memberId, orderid, otype);
				}
			} finally {
				lock.unlock();
			}
			checkArgument(backpayCode == 1, "退出失败");
			return Result.success();
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

	/**
	 * 验证团组是否满员
	 * 
	 * @param groupno
	 *            团号
	 * @return
	 */
	@ApiOperation(value = "验证团组是否满员", response = Acgroup.class)
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupno", value = "团号", required = true, paramType = "query"), })
	@PostMapping("/validateacgroup")
	public Object validateacgroup(@RequestParam String groupno) {
		try {
			List<Acgroup> acgroups = acgrouopService.validateAcgroup(groupno);
			return Result.success();
		} catch (Exception e) {
			return GetException.getCatch(e, log);
		}
	}

}
